package com.imdroid.lite.services;

import android.content.Intent;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import com.imdroid.lite.IMDroid;
import com.imdroid.lite.R;
import com.imdroid.lite.activities.TeamMapActivity;
import com.imdroid.lite.model.Team;
import com.imdroid.lite.model.TeamMember;
import com.imdroid.lite.model.TeamTalk;
import com.imdroid.lite.process.PlaySoundProcess;

/**
 * The action handler of notification
 * 
 */
public class NotificationHandler extends Handler {
	private static final String TAG = "NotificationHandler";

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.os.Handler#handleMessage(android.os.Message)
	 */
	public void handleMessage(android.os.Message msg) {
		switch (msg.what) {
		case NotificationService.CONNECTED:
			Toast.makeText(
					IMDroid.getAppContext(),
					IMDroid.getAppContext()
							.getString(R.string.server_connected),
					Toast.LENGTH_SHORT).show();
			break;
		case NotificationService.CONNECT_FAIL:
			Toast.makeText(
					IMDroid.getAppContext(),
					IMDroid.getAppContext().getString(
							R.string.server_connect_fail), Toast.LENGTH_SHORT)
					.show();
			break;
		case NotificationService.RECEIVED:
			// 处理通知事件
			Log.d(TAG, msg.obj + "");
			
			// 文字信息
			if (msg.obj instanceof String) {
				handleNotification("" + msg.obj);
			}
			
			// 语音信息
			if (msg.obj instanceof TeamTalk) {
				PlaySoundProcess.speak2((TeamTalk) msg.obj);
			}

			break;
		case NotificationService.DISCONNECTED:
			Toast.makeText(
					IMDroid.getAppContext(),
					IMDroid.getAppContext().getString(
							R.string.server_disconnect), Toast.LENGTH_SHORT)
					.show();
			break;
		}
	}

	/**
	 * handle the notification message
	 * 
	 * @param message
	 *            the message
	 */
	private void handleNotification(String message) {
		String text[] = message.split("&&");

		// 判断消息格式是否正确
		if (text == null || text.length < 2 || text[0] == null
				|| "".equals(text[0])) {
			return;
		}
		int n = Integer.parseInt(text[0]);

		switch (n) {
		case NotificationMessage.NOTIFICATION_PING:
			ping();
			break;
		case NotificationMessage.NOTIFICATION_CALL:
			// 播出对讲的声音文件
			String soundFile = text[1].trim();
			int deviceId = Integer.parseInt(text[2].trim());
			String deviceName = text[3].trim();
			speak(soundFile, deviceId, deviceName);
			break;
		case NotificationMessage.NOTIFICATION_LOCATION:
			// 更新队友GPS位置
			Float userId = Float.parseFloat(text[1]);
			float longitude = Float.parseFloat(text[2]);
			float latitude = Float.parseFloat(text[3]);
			float speed = Float.parseFloat(text[4]);
			String userName = text[5];
			float direction = Float.parseFloat(text[6]);
			String deviceType = text[7];
			refreshTeam(userId.intValue(), longitude, latitude, speed, userName,direction, deviceType);
			break;
		case NotificationMessage.NOTIFICATION_ADDTOTEAM:
			// 加入队伍邀请
			String[] items = text[1].split(";");
			addToTeam(items[0], items[1], items[2]);
			break;
		case NotificationMessage.NOTIFICATION_CONFIRM:
			joinTeam();
			break;
		case NotificationMessage.NOTIFICATION_EXIT:
			// 用户退出当前队伍
			exitTeam();
			break;
		case NotificationMessage.NOTIFICATION_TEAMDESTINATION:
			// 接受到目的地
			if (text.length >= 5) {
				String name = text[1];
				float dest_lat = Float.parseFloat(text[2]);
				float dest_lon = Float.parseFloat(text[3]);
				boolean routeSearch = text[4].trim().equals("1");
				recevieTeamDestination(name, dest_lat, dest_lon, routeSearch);
			}
			break;
		}
	}

	/**
	 * Receive the ping message
	 */
	private void ping() {
//		Toast.makeText(IMDroid.getAppContext(), "Ping", Toast.LENGTH_SHORT)
//				.show();
	}

	/**
	 * 播出语音信息
	 */
	private void speak(String soundFile, int deviceId, String deviceName) {
		TeamTalk tt = new TeamTalk();
		tt.setMemberId(deviceId);
		tt.setMemberName(deviceName);
		tt.setFileNameInServer(soundFile);
		tt.setFile(IMDroid.TEMP_FOLDER + soundFile);

		PlaySoundProcess.speak(tt);

	}

	/**
	 * Other team member confirm to join
	 */
	private void joinTeam() {
		// 播放声音
		PlaySoundProcess.playSound(PlaySoundProcess.confirm);
		// 刷新队员列表
		TeamMapActivity instance = TeamMapActivity.instance;
		if (instance != null && instance.isActive()) {
			instance.getHandler().sendEmptyMessage(
					TeamMapActivity.EVENT_TEAM_REFRESH);
		}
	}

	/**
	 * 退出队伍
	 */
	private void exitTeam() {
		// 播放声音
		PlaySoundProcess.playSound(PlaySoundProcess.exit);

		// 刷新队员列表
		TeamMapActivity instance = TeamMapActivity.instance;
		if (instance != null && instance.isActive()) {
			instance.getHandler().sendEmptyMessage(
					TeamMapActivity.EVENT_TEAM_REFRESH);
		}
	}

	/**
	 * Refresh the user's location
	 * 
	 * @param userId
	 *            the target user id
	 * @param longitude
	 *            the user's location - longitude
	 * @param latitude
	 *            the user's location - latitude
	 * @param name
	 *            the user's name
	 */
	private void refreshTeam(int userId, float longitude, float latitude,
			float speed, String userName, float direction, String deviceType) {
		Team team = Team.getCurrentTeam();
		if (team == null || team.getMembers() == null)
			return;
		// 更改缓存中的对象
		TeamMember member = team.getMembers().get(userId);
		if (member != null) {
			Log.d(TAG, "--" + member.getDisplayName() + " " + latitude + " "
					+ longitude);
			member.setLat(latitude);
			member.setLon(longitude);
			member.setSpeed(speed);
			member.setDirect(direction);
			member.setDeviceType(deviceType);
		}

		// 刷新队员列表
		TeamMapActivity instance = TeamMapActivity.instance;
		if (instance != null && instance.isActive()) {
			instance.getHandler().sendEmptyMessage(
					TeamMapActivity.EVENT_TEAM_UPDATE);
		}
		return;
	}

	/**
	 * Add to the team number
	 * 
	 * @param message
	 *            The message from the invitation.
	 */
	private void addToTeam(String user, String teamId, String teamName) {
		// 重启动服务
		if (!NotificationService.isLive()) {
			Intent i = new Intent(Intent.ACTION_RUN);
			i.setClass(IMDroid.getAppContext(), NotificationService.class);
			IMDroid.getAppContext().stopService(i);

			try {
				Thread.sleep(3 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			IMDroid.getAppContext().startService(i);
		}

		// TeamInviteDialog.showInviteDialog(user, teamId, teamName);
		return;
	}

	/**
	 * Receive the desiniation
	 * 
	 * @param destination
	 *            the name of destination
	 * @param lat
	 *            latitude of the destination
	 * @param lon
	 *            longitude of the destination
	 * @param routeSearch
	 *            if need the search the route when setting the desination
	 */
	private void recevieTeamDestination(String destination, float lat,
			float lon, boolean routeSearch) {
		if (Team.getCurrentTeam() != null) {
			Team.getCurrentTeam().setDestinationName(destination);
			Team.getCurrentTeam().setDestinationLat(lat);
			Team.getCurrentTeam().setDestinationLon(lon);
			Team.getCurrentTeam().setSearchRoute(routeSearch);

			PlaySoundProcess.playSound(PlaySoundProcess.confirm);
			TeamMapActivity instance = TeamMapActivity.instance;

			instance.getHandler().sendEmptyMessage(
					TeamMapActivity.EVENT_TEAM_RECEIVE_LOCATION);

			Toast.makeText(
					instance,
					IMDroid.getAppContext().getResources()
							.getString(R.string.team_map_destination),
					Toast.LENGTH_LONG).show();
		}
	}

	/**
	 * The message of notification
	 * 
	 */
	private class NotificationMessage {
		/**
		 * The type of notification - empty information to maintain the
		 * connection
		 */
		public static final int NOTIFICATION_PING = 101;
		/**
		 * The type of notification - call
		 */
		public static final int NOTIFICATION_CALL = 102;
		/**
		 * The type of notification - GPS location
		 */
		public static final int NOTIFICATION_LOCATION = 103;
		/**
		 * The type of notification - GPS location
		 */
		public static final int NOTIFICATION_ADDTOTEAM = 104;

		/**
		 * Team cancel(or exit the team)
		 */
		// public static final int NOTIFICATION_TEAM_CANCEL = 105;

		/**
		 * The type of notification - confirm add.
		 */
		public static final int NOTIFICATION_CONFIRM = 106;

		/**
		 * The type of notification - user exit the current team
		 */
		public static final int NOTIFICATION_EXIT = 108;
		/**
		 * The type of notification - exit from the team
		 */
		public static final int NOTIFICATION_TEAMDESTINATION = 110;
		/**
		 * The type of notification - receive the destination
		 */
		// public static final int NOTIFICATION_Destination = 109;
	}

}
